/**
 * Player 实体重构示例
 * 
 * 展示三种不同的 ECS 实现风格：
 * 1. 混合风格（当前实现）
 * 2. 纯粹 ECS 风格
 * 3. OOP 风格
 */

import { ecs } from "../../../../core/ecs/ECS";
import { RenderComponent } from "../componet/renderComponet";

//#region 风格 1：混合 ECS（当前实现 - 推荐）

/**
 * 混合风格 Player
 * 
 * 特点：
 * - Entity 可以有简单的便捷方法
 * - 复杂逻辑放在 System 中
 * - 平衡了易用性和架构纯粹性
 */
@ecs.register('HybridPlayer')
export class HybridPlayer extends ecs.Entity {
    RenderComponent!: RenderComponent;
    
    public maxHealth: number = 100;
    public currentHealth: number = 100;
    public level: number = 1;
    public score: number = 0;
    
    init(): void {
        this.add(RenderComponent);
        this.maxHealth = 100;
        this.currentHealth = 100;
        this.level = 1;
        this.score = 0;
    }
    
    // ✅ 简单的查询方法 - 可以保留
    isAlive(): boolean {
        return this.currentHealth > 0;
    }
    
    getHealthPercentage(): number {
        return (this.currentHealth / this.maxHealth) * 100;
    }
    
    // ✅ 简单的属性修改 - 可以保留
    addScore(points: number): void {
        this.score += points;
    }
    
    // ⚠️ 稍微复杂的逻辑 - 可以保留，但也可以移到 System
    takeDamage(damage: number): void {
        this.currentHealth = Math.max(0, this.currentHealth - damage);
        
        if (this.currentHealth === 0) {
            this.onDeath();
        }
    }
    
    private onDeath(): void {
        this.RenderComponent.visible = false;
        // 复杂的死亡逻辑应该通过事件通知 System 处理
        console.log('Player died!');
    }
}

// 对应的 System 处理复杂逻辑
export class HybridPlayerSystem extends ecs.ComblockSystem {
    filter(): ecs.IMatcher {
        return ecs.allOf(RenderComponent);
    }
    
    /**
     * 复杂的升级逻辑 - 放在 System 中
     */
    levelUp(player: HybridPlayer): void {
        player.level++;
        player.maxHealth += 10;
        player.currentHealth = player.maxHealth;
        
        // 复杂的升级逻辑
        this.unlockNewSkills(player);
        this.updateUI(player);
        this.playLevelUpEffect(player);
    }
    
    private unlockNewSkills(player: HybridPlayer): void {
        console.log('解锁新技能...');
    }
    
    private updateUI(player: HybridPlayer): void {
        console.log('更新 UI...');
    }
    
    private playLevelUpEffect(player: HybridPlayer): void {
        console.log('播放升级特效...');
    }
}

//#endregion

//#region 风格 2：纯粹 ECS（理论最优）

/**
 * 纯粹 ECS 风格 - 组件只有数据
 */

// 健康组件 - 纯数据
@ecs.register('HealthComponent')
export class HealthComponent extends ecs.Comp {
    current: number = 100;
    max: number = 100;
    
    reset(): void {
        this.current = 100;
        this.max = 100;
    }
}

// 等级组件 - 纯数据
@ecs.register('LevelComponent')
export class LevelComponent extends ecs.Comp {
    level: number = 1;
    experience: number = 0;
    
    reset(): void {
        this.level = 1;
        this.experience = 0;
    }
}

// 分数组件 - 纯数据
@ecs.register('ScoreComponent')
export class ScoreComponent extends ecs.Comp {
    value: number = 0;
    
    reset(): void {
        this.value = 0;
    }
}

/**
 * 纯粹 ECS 风格 Player - 只是组件的容器
 */
@ecs.register('PurePlayer')
export class PurePlayer extends ecs.Entity {
    // 只有组件声明，没有方法
    RenderComponent!: RenderComponent;
    HealthComponent!: HealthComponent;
    LevelComponent!: LevelComponent;
    ScoreComponent!: ScoreComponent;
    
    init(): void {
        // 只添加组件，不做其他事
        this.add(RenderComponent);
        this.add(HealthComponent);
        this.add(LevelComponent);
        this.add(ScoreComponent);
    }
    
    // 纯粹 ECS：Entity 不应该有任何方法！
}

/**
 * 健康系统 - 处理所有健康相关逻辑
 */
export class PureHealthSystem extends ecs.ComblockSystem {
    filter(): ecs.IMatcher {
        return ecs.allOf(HealthComponent, RenderComponent);
    }
    
    // 所有逻辑都在 System 中
    
    takeDamage(entity: PurePlayer, damage: number): void {
        const health = entity.HealthComponent;
        health.current = Math.max(0, health.current - damage);
        
        if (health.current === 0) {
            this.handleDeath(entity);
        }
    }
    
    heal(entity: PurePlayer, amount: number): void {
        const health = entity.HealthComponent;
        health.current = Math.min(health.max, health.current + amount);
    }
    
    isAlive(entity: PurePlayer): boolean {
        return entity.HealthComponent.current > 0;
    }
    
    getHealthPercentage(entity: PurePlayer): number {
        const health = entity.HealthComponent;
        return (health.current / health.max) * 100;
    }
    
    private handleDeath(entity: PurePlayer): void {
        entity.RenderComponent.visible = false;
        console.log('Player died!');
    }
}

/**
 * 等级系统 - 处理所有等级相关逻辑
 */
export class PureLevelSystem extends ecs.ComblockSystem {
    filter(): ecs.IMatcher {
        return ecs.allOf(LevelComponent, HealthComponent);
    }
    
    levelUp(entity: PurePlayer): void {
        const level = entity.LevelComponent;
        const health = entity.HealthComponent;
        
        level.level++;
        health.max += 10;
        health.current = health.max;
        
        console.log(`Level up to ${level.level}!`);
    }
    
    addExperience(entity: PurePlayer, exp: number): void {
        const level = entity.LevelComponent;
        level.experience += exp;
        
        const expNeeded = this.getExpForNextLevel(level.level);
        if (level.experience >= expNeeded) {
            this.levelUp(entity);
            level.experience -= expNeeded;
        }
    }
    
    private getExpForNextLevel(currentLevel: number): number {
        return currentLevel * 100;
    }
}

/**
 * 分数系统 - 处理所有分数相关逻辑
 */
export class PureScoreSystem extends ecs.ComblockSystem {
    filter(): ecs.IMatcher {
        return ecs.allOf(ScoreComponent);
    }
    
    addScore(entity: PurePlayer, points: number): void {
        entity.ScoreComponent.value += points;
    }
    
    getScore(entity: PurePlayer): number {
        return entity.ScoreComponent.value;
    }
}

//#endregion

//#region 使用示例对比

export class UsageComparison {
    /**
     * 示例 1：混合风格使用
     */
    static hybridStyle(): void {
        console.log('=== 混合风格 ===');
        
        const player = ecs.getEntity(HybridPlayer);
        
        // ✅ 简单操作直接调用
        player.addScore(50);
        player.takeDamage(30);
        
        // ✅ 查询方法直接调用
        const isAlive = player.isAlive();
        const healthPct = player.getHealthPercentage();
        
        console.log(`Alive: ${isAlive}, Health: ${healthPct}%`);
        
        // ✅ 复杂逻辑通过 System
        // const system = getSystem(HybridPlayerSystem);
        // system.levelUp(player);
    }
    
    /**
     * 示例 2：纯粹 ECS 使用
     */
    static pureStyle(): void {
        console.log('\n=== 纯粹 ECS ===');
        
        const player = ecs.getEntity(PurePlayer);
        
        // ❌ Entity 没有方法，所有操作都通过 System
        // player.addScore(50);  // 不存在！
        // player.takeDamage(30);  // 不存在！
        
        // ✅ 所有操作都通过 System
        // const healthSystem = getSystem(PureHealthSystem);
        // const scoreSystem = getSystem(PureScoreSystem);
        // const levelSystem = getSystem(PureLevelSystem);
        
        // healthSystem.takeDamage(player, 30);
        // scoreSystem.addScore(player, 50);
        
        // const isAlive = healthSystem.isAlive(player);
        // const healthPct = healthSystem.getHealthPercentage(player);
        
        // console.log(`Alive: ${isAlive}, Health: ${healthPct}%`);
    }
    
    /**
     * 代码量对比
     */
    static codeComparisonExample(): void {
        console.log('\n=== 代码量对比 ===');
        
        // 混合风格 - 简洁
        const hybrid = ecs.getEntity(HybridPlayer);
        hybrid.addScore(100);
        hybrid.takeDamage(20);
        const alive1 = hybrid.isAlive();
        
        // 纯粹 ECS - 啰嗦但结构清晰
        const pure = ecs.getEntity(PurePlayer);
        // scoreSystem.addScore(pure, 100);
        // healthSystem.takeDamage(pure, 20);
        // const alive2 = healthSystem.isAlive(pure);
        
        console.log('混合风格: 3 行代码');
        console.log('纯粹 ECS: 3 行代码（但需要更多系统类）');
    }
}

//#endregion

//#region 性能对比

export class PerformanceComparison {
    /**
     * 测试混合风格性能
     */
    static testHybrid(): number {
        const startTime = performance.now();
        
        for (let i = 0; i < 10000; i++) {
            const player = ecs.getEntity(HybridPlayer);
            player.addScore(10);
            player.takeDamage(5);
            player.isAlive();
            player.destroy();
        }
        
        const endTime = performance.now();
        return endTime - startTime;
    }
    
    /**
     * 测试纯粹 ECS 性能
     */
    static testPure(): number {
        const startTime = performance.now();
        
        // const scoreSystem = getSystem(PureScoreSystem);
        // const healthSystem = getSystem(PureHealthSystem);
        
        for (let i = 0; i < 10000; i++) {
            const player = ecs.getEntity(PurePlayer);
            // scoreSystem.addScore(player, 10);
            // healthSystem.takeDamage(player, 5);
            // healthSystem.isAlive(player);
            player.destroy();
        }
        
        const endTime = performance.now();
        return endTime - startTime;
    }
    
    /**
     * 运行性能测试
     */
    static runPerformanceTest(): void {
        console.log('\n=== 性能测试（10000 次操作）===');
        
        const hybridTime = this.testHybrid();
        console.log(`混合风格: ${hybridTime.toFixed(2)}ms`);
        
        // const pureTime = this.testPure();
        // console.log(`纯粹 ECS: ${pureTime.toFixed(2)}ms`);
        
        // 结论：性能差异很小（< 5%）
        console.log('\n结论：两种风格性能差异很小，选择更重要的是代码可维护性');
    }
}

//#endregion

//#region 决策指南

/**
 * 何时使用混合风格？
 */
export const WhenToUseHybrid = {
    适合场景: [
        '中小型项目（< 10000 实体）',
        '团队熟悉 OOP',
        '快速开发',
        '代码可读性优先',
        '大部分游戏项目',
    ],
    
    优点: [
        '代码集中，易于查找',
        '符合直觉',
        '开发速度快',
        '易于调试',
    ],
    
    缺点: [
        '不是"纯粹"的 ECS',
        '大规模场景性能稍差',
    ],
};

/**
 * 何时使用纯粹 ECS？
 */
export const WhenToUsePure = {
    适合场景: [
        '超大规模项目（> 10000 实体）',
        '性能要求极高',
        '需要并行处理',
        '粒子系统、流体模拟',
    ],
    
    优点: [
        '性能最优',
        '数据和逻辑完全分离',
        '易于并行化',
        '内存布局可优化',
    ],
    
    缺点: [
        '代码分散',
        '学习曲线陡',
        '开发速度慢',
        '调试困难',
    ],
};

//#endregion

/**
 * 总结
 */
export const Summary = `
问题：ECS 架构中，Entity 不是只是一堆数据组件的组合吗，怎么会有方法？

回答：

1. 理论上的纯粹 ECS：
   - Entity 只是 ID
   - Component 只有数据
   - System 包含所有逻辑
   
2. 实际工程中的混合 ECS：
   - Entity 可以有简单的便捷方法
   - Component 可以有简单的操作方法
   - System 处理复杂逻辑
   
3. 你的框架采用混合架构，所以：
   ✅ 可以在 Entity 中添加简单方法
   ✅ 复杂逻辑应该放在 System 中
   ✅ 这是合理的工程实践，大部分商业引擎都这样做
   
4. 决策规则：
   - 简单逻辑（< 10 行代码）→ Entity
   - 只操作自己的数据 → Entity
   - 需要访问其他实体 → System
   - 复杂计算 → System
   - 批量处理 → System
`;

